package cn.yunyichina.provider.pay.service.impl;

import cn.yunyichina.provider.framework.dubbo.service.HymedService;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.dto.hymed.MedicalCardQueryRequestDTO;
import cn.yunyichina.provider.iface.entity.dto.hymed.MedicalCardQueryResponseDTO;
import cn.yunyichina.provider.iface.entity.dto.hymed.PaymentBalanceRequestDTO;
import cn.yunyichina.provider.iface.entity.dto.hymed.PaymentBalanceResponseDTO;
import cn.yunyichina.provider.iface.entity.pay.PayCode;
import cn.yunyichina.provider.pay.constant.ResponseEnum;
import cn.yunyichina.provider.pay.entity.PaymentSetting;
import cn.yunyichina.provider.pay.exception.PaySettingNotFoundException;
import cn.yunyichina.provider.pay.service.BalanceService;
import cn.yunyichina.provider.pay.service.BaseService;
import cn.yunyichina.utils.convert.JsonUtils;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * 余额查询
 * Created by Lullaby on 2017/10/25
 */
@Service
public class BalanceServiceImpl extends BaseService implements BalanceService {

    private static final Logger logger = LoggerFactory.getLogger(BalanceServiceImpl.class);

    /**
     * 查询余额接口
     *
     * @param params
     * @return
     */
    public ResponseObject queryBalance(String params) {
        logger.info("BalanceServiceImpl.queryBalance.params -> {}", params);

        try {
            Map map = JsonUtils.parseObject(params, Map.class);
            assert map != null;
            String payCode = (String) map.get("pay_code");
            switch (PayCode.valueOf(payCode)) {
                case HYMEDUNION:
                    return queryHymedUnionBalance(map);
                default:
                    return new ResponseObject().buildResultCodeAndMessage(
                            ResponseEnum.UNSUPPORTED.getCode(),
                            ResponseEnum.UNSUPPORTED.getMessage()
                    );
            }
        } catch (PaySettingNotFoundException e) {
            logger.error("BalanceServiceImpl.queryBalance.PaySettingNotFoundException", e);
            return new ResponseObject().buildResultCodeAndMessage(
                    ResponseEnum.PAY_SETTING_NOT_FOUND.getCode(),
                    ResponseEnum.PAY_SETTING_NOT_FOUND.getMessage()
            );
        } catch (Exception e) {
            logger.error("BalanceServiceImpl.queryBalance.Exception", e);
            return new ResponseObject().buildResultCodeAndMessage(
                    ResponseEnum.QUERY_BALANCE_EXCEPTION.getCode(),
                    ResponseEnum.QUERY_BALANCE_EXCEPTION.getMessage()
            );
        }
    }

    /**
     * 查询河源一卡通余额
     *
     * @param params
     * @return
     */
    private ResponseObject queryHymedUnionBalance(Map params) throws PaySettingNotFoundException {
        String appCode = (String) params.get("app_code");
        String orgCode = (String) params.get("org_code");
        String payCode = (String) params.get("pay_code");
        String account = (String) params.get("insurance_login_name");
        if (StringUtils.isEmpty(appCode) ||
                StringUtils.isEmpty(orgCode) ||
                StringUtils.isEmpty(account)) {
            return invalidPayParamsResponseObject();
        }

        short payMode = (short) getPayModeByPayCode(payCode);

        MedicalCardQueryRequestDTO queryRequestDTO = new MedicalCardQueryRequestDTO();
        queryRequestDTO.setAccount(account);
        queryRequestDTO.setAppCode(appCode);
        queryRequestDTO.setOrgCode(orgCode);
        queryRequestDTO.setPayCode(payCode);

        ResCommon<MedicalCardQueryResponseDTO> cardQueryResponse = HymedService.getHyMedClient().queryMedicareCard(queryRequestDTO);
        logger.info("BalanceServiceImpl.queryHymedUnionBalance.cardQueryResponse -> {}", JSON.toJSONString(cardQueryResponse));
        if (!cardQueryResponse.isSuccess()) {
            return new ResponseObject().buildResultCodeAndMessageAndResult(
                    cardQueryResponse.getResultCode(),
                    cardQueryResponse.getResultMessage(),
                    cardQueryResponse.getResult()
            );
        }

        MedicalCardQueryResponseDTO queryResponseDTO = cardQueryResponse.getResult();
        PaymentSetting paymentSetting = getPaymentSetting(appCode, orgCode, payMode);

        PaymentBalanceRequestDTO balanceRequestDTO = new PaymentBalanceRequestDTO();
        balanceRequestDTO.setAppCode(appCode);
        balanceRequestDTO.setOrgCode(orgCode);
        balanceRequestDTO.setPayCode(payCode);
        balanceRequestDTO.setMer_cd(paymentSetting.getMerchantAccount());
        balanceRequestDTO.setMer_nm(paymentSetting.getOrgName());
        balanceRequestDTO.setAccno(queryResponseDTO.getPersonal_account());
        balanceRequestDTO.setCertiftp("00");
        balanceRequestDTO.setCertifid(queryResponseDTO.getId_number());
        balanceRequestDTO.setCustomernm(queryResponseDTO.getFull_name());
        balanceRequestDTO.setRcvlnst(queryResponseDTO.getBank_account_open());
        balanceRequestDTO.setCardsn(queryResponseDTO.getBank_account());
        balanceRequestDTO.setIssudt(queryResponseDTO.getRelease_time());
        balanceRequestDTO.setCardexp(queryResponseDTO.getValid_time());
        logger.info("BalanceServiceImpl.queryHymedUnionBalance.balanceRequestDTO -> {}", JSON.toJSONString(balanceRequestDTO));

        ResCommon<PaymentBalanceResponseDTO> balanceQueryResponse = HymedService.getHyMedClient().balancePayment(balanceRequestDTO);
        logger.info("BalanceServiceImpl.queryHymedUnionBalance.balanceQueryResponse -> {}", JSON.toJSONString(balanceQueryResponse));
        if (!balanceQueryResponse.isSuccess()) {
            return new ResponseObject().buildResultCodeAndMessageAndResult(
                    balanceQueryResponse.getResultCode(),
                    balanceQueryResponse.getResultMessage(),
                    balanceQueryResponse.getResult()
            );
        }

        return new ResponseObject().buildResultObject(balanceQueryResponse.getResult());
    }

}
